package com.joe.util.htmlparse;


import com.joe.util.htmlparse.exception.HttpFetchException;
import com.joe.util.htmlparse.model.HttpResponseModel;
import org.apache.commons.lang3.StringUtils;
import org.htmlcleaner.HtmlCleaner;
import org.htmlcleaner.TagNode;
import org.htmlcleaner.XPatherException;

import java.util.ArrayList;
import java.util.List;

public class HtmlUtils {

    public static final HtmlCleaner CLEANER = new HtmlCleaner();

    private static final int DEFAULT_TRY_TIMES = 1;

    public static HttpResponseModel getResponse(String url, int tryTimes) {
        HttpResponseModel responseModel = new HttpResponseModel(-1, "", "UTF-8", new byte[0], "", null);

        if (tryTimes <= 0) {
            tryTimes = 1;
        }

        for (int retry = 0; retry < tryTimes; retry++) {
            responseModel = HttpUtils.get(url, null);

            if (responseModel.getStatusCode() > 300 && responseModel.getStatusCode() < 400) {
                if (StringUtils.isEmpty(responseModel.getRedirect())) {
                    responseModel = HttpUtils.get(responseModel.getRedirect(), null);
                }
            }

            boolean hasError = responseModel.isHasException();
            if (hasError) {
                continue;
            } else {
                return responseModel;
            }
        }
        return responseModel;
    }

    public static TagNode getUrlRootTagNode(String url) throws HttpFetchException {
        HttpResponseModel response = getResponse(url, DEFAULT_TRY_TIMES);
        if (response.isHasException() || response.getStatusCode() != 200) {
            if (response.getStatusCode() == 500) {
                try {
                    Thread.sleep(1500

                    );
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                response = getResponse(url, DEFAULT_TRY_TIMES);
                if (response.isHasException() || response.getStatusCode() != 200) {
                    throw new HttpFetchException("HTTP " + String.valueOf(response.getStatusCode()) +
                            " url : " + url);
                }
            } else {
                throw new HttpFetchException("HTTP " + String.valueOf(response.getStatusCode()) +
                        " url : " + url);
            }
        }
        String html = response.getBodyString();
        return CLEANER.clean(html);
    }

    public static String getUrlHtml(String url) throws HttpFetchException {
        HttpResponseModel response = getResponse(url, DEFAULT_TRY_TIMES);
        if (response.isHasException() || response.getStatusCode() != 200) {
            throw new HttpFetchException("HTTP " + String.valueOf(response.getStatusCode()) +
                    " url : " + url);
        }
        return response.getBodyString();
    }

    public static List<TagNode> getSubNodesByXPath(TagNode node, String xpath) throws XPatherException {
        ArrayList<TagNode> result = new ArrayList<TagNode>();
        try {
            Object[] nodes = node.evaluateXPath(xpath);
            if (nodes == null) {
                return null;
            }
            for (Object subNode : nodes) {
                result.add((TagNode) subNode);
            }
            return result;
        } catch (XPatherException e) {
            throw e;
        }
    }

}
